using UnityEngine;
using System.Collections;

/**
 * Script of menu behaviour description.
 * The purpose of this class is to emulate GUI.
 * @author Benjamin Bruneau
 */
public class DetectClickOnObjectScript : MonoBehaviour 
{
	
	private const string DATA_CONTAINER_NAME = "Result"; // Data Container GameObject's name
	private const string MOUSE_CURSOR_MANAGER_NAME = "MouseCursorManager"; // MouseCursorManager GameObject's name
	private const string SAVE_MANAGER_NAME = "SaveManager"; // SaveManager GameObject's name
	private const string REPLAY_MODE_NAME = "ReplayMode"; // Replay Mode GameObject's name
	private const string FORWARD_QUIT = "Quit"; // Quit Forward
	private const string FORWARD_RETRY = "Retry"; // Retry Forward
	private const string FORWARD_RESUME = "Resume"; // Resume Forward
	private const string FORWARD_MENUSCENE = "MenuScene"; // MenuScene Forward
	
	private bool _mouseMoved; // Has the mouse moved
	
	private Vector3 _mousePreviousPosition; // Mouse previous position
	
	private GameObject _dataContainer; // Data container GameObject
	private GameObject _replayMode; // Replay mode GameObject
	private GameObject _mouseCursorManager; // Mouse Cursor Manager GameObject
	private GameObject _saveManager; // Mouse Cursor Manager GameObject
	
	public GameObject _pauseManager; // Pause Manager GameObject
	public GameObject _menuSelectSound; // Menu Select Sound GameObject
	public GameObject _menuAction; // Menu Select Sound GameObject
	public GameObject _selectableTexts; // Selectable Texts GameObject
	public GameObject _embeddedCamera; // Embedded Camera GameObject
	public GameObject _top; // Text on top GameObject
	public GameObject _left; // Text on left GameObject
	public GameObject _right; // Text on right GameObject
	public GameObject _bottom; // Text on bottom GameObject
	
	public string _forward; //Application next scene
	public string _textOriginal; // 3DText
	public string _textSelected; // 3DText on selection
	
	public bool _selected; // If selected Text
	public bool _isReplayMode; // Replay mode
	
	/**
	 * Called on initialization.
	 * @return void
	 */
	void Start () 
	{

		//Initialized because these objects moves through scenes
		_dataContainer = GameObject.Find (DATA_CONTAINER_NAME);
		_replayMode = GameObject.Find (REPLAY_MODE_NAME);
		_mouseCursorManager = GameObject.Find (MOUSE_CURSOR_MANAGER_NAME);
		_saveManager = GameObject.Find (SAVE_MANAGER_NAME);
		
	}
		
	/**
	 * Called on mouse enter.
	 * @return void
	 */
	void OnMouseEnter () 
	{
		
		// Select actual field
		deselectAll();
		_selected = true;
		_selectableTexts.GetComponent<MenuControllerScript>()._selectedChild = this.gameObject;
		_menuSelectSound.GetComponent<AudioSource>().Play();
	}
		
	/**
	 * Called once per frame.
	 * @return void
	 */
	void Update ()
	{
		
		// Has the mouse moved since last frame
		if(_mousePreviousPosition != Input.mousePosition)
		{
			_mousePreviousPosition = Input.mousePosition;
			_mouseMoved = true;
			
		}
		
		// If this field is selected
		if(_selected)
		{		
			// Text state on selection
			this.gameObject.GetComponent<TextMesh>().text = _textSelected;
			this.gameObject.GetComponent<TextMesh>().characterSize = 1.2f;	
			this.gameObject.GetComponent<MeshRenderer>().material.color = Color.yellow;
			
		} else {
			
			pauseMouseManagement ();
			
			// Text state without selection
			this.gameObject.GetComponent<TextMesh>().text = _textOriginal;
			this.gameObject.GetComponent<TextMesh>().characterSize = 1f;
			this.gameObject.GetComponent<MeshRenderer>().material.color = Color.white;
		}
		
		forwardOnClick ();
		_mouseMoved = false;	
	}

	/**
	 * Mouse management while timescale is 0.
	 * @return void
	 */
	private void pauseMouseManagement ()
	{
		
		// If mouse moved since last frame
		if(_mouseMoved)
		{
			// If the pause manager exists
			if(_pauseManager != null)
			{
				// If pause mode
				if(_pauseManager.GetComponent<PauseControllerScript>()._pause)
				{
					// Getting camera
					Camera cam = Camera.main;
					if(cam == null)
					{
						cam = _embeddedCamera.GetComponent<Camera>();
					}
					
					// Raycast
					Ray ray = cam.ScreenPointToRay(Input.mousePosition);
					RaycastHit hit = new RaycastHit();
					
					// If collide
					if (this.collider.Raycast (ray, out hit, 100f))
					{
						// Select this
						deselectAll();
						_selected = true;
						_selectableTexts.GetComponent<MenuControllerScript>()._selectedChild = this.gameObject;
						_menuSelectSound.GetComponent<AudioSource>().Play();
					}
				}
			}
		}		
	}
	
	/*
	 * Action of button manager.
	 * @return void
	 */
	private void forwardOnClick ()
	{
		//On click
		if (Input.GetMouseButton(0))
		{
			//Ray send
			Camera cam = Camera.main;
			if(cam == null)
			{
				cam = _embeddedCamera.GetComponent<Camera>();
			}
			Ray ray = cam.ScreenPointToRay(Input.mousePosition);
			
			RaycastHit hit = new RaycastHit();
			
			// If collide
			if (this.collider.Raycast (ray, out hit, 100f))
			{
				forwardScene ();
			}
		}
	}
	
	/*
	 * Forwarding after click or keypress.
	 * @return void
	 */
	public void forwardScene ()
	{
		
		_menuAction.GetComponent<AudioSource>().Play();
		
		// Unpause if action comes from pause
		if(_pauseManager != null)
		{
			if(_pauseManager.GetComponent<PauseControllerScript>()._pause)
			{
				Time.timeScale = 1;
			}
		}
		// If action is not Resume
		if (!_forward.Equals(FORWARD_RESUME))
		{
			//Quit Game
			if (_forward.Equals(FORWARD_QUIT))
			{
				Application.Quit();
				
			} else {
				
				string currentLevel = "";
				//Result Destroyer (persistent)
				if (_dataContainer != null)
				{
					currentLevel = _dataContainer.GetComponent<DataContainerScript>()._currentLevel;
					Destroy(_dataContainer);
				}
				//If forward is the menu
				if(_forward.Equals(FORWARD_MENUSCENE))
				{
					Destroy (_mouseCursorManager);
					Destroy (_saveManager);
					
					if (_replayMode != null)
					{
						Destroy(_replayMode);
					}
				}
				
				// If replay mode
				if(_isReplayMode)
					{
						_replayMode.GetComponent<ReplayModeScript>()._replayMode = true;
					}
				
				// If forward is retry
				if(_forward.Equals(FORWARD_RETRY))
				{
					_forward = currentLevel;
					_replayMode.GetComponent<ReplayModeScript>()._replayMode = false;
				}
				
				// Next scene
				Application.LoadLevel(_forward);
			}
		
		} else {
			
			// Unpause
			_pauseManager.GetComponent<PauseControllerScript>().unpause();		
		}		
	}
	
	/*
	 * Buttons deselection.
	 * @return void
	 */
	private void deselectAll()
	{
		DetectClickOnObjectScript[] tabDetectClickOnObjectScript = _selectableTexts.GetComponentsInChildren<DetectClickOnObjectScript>();
			
		foreach (DetectClickOnObjectScript detectClickOnObjectScript in tabDetectClickOnObjectScript) 
			{ 
				detectClickOnObjectScript._selected = false;
			}
	}	
}
